home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-30 | 11.3 KB | 385 lines | [TEXT/CWIE] |
- UNIT PopupDialog;
- INTERFACE
- USES
- {$IFC UNDEFINED THINK_PASCAL}
- {$SETC THINK_PASCAL=FALSE}
- {$ENDC}
- {$IFC THINK_PASCAL=FALSE}
- Types, ToolUtils, Resources, Controls, Menus, Memory, QuickDraw, QuickDrawText, OSUtils, Events, Dialogs, Windows, Fonts,
- {$ENDC}
- LowMem, MercutioAPI;
- CONST
- Off = 0;
- On = 1;
- Disable = 255;
-
- enterKey = 3;
- helpKey = 5;
- deleteKey = 8;
- tabKey = 9;
- linefeedKey = 10;
- CR = 13;
-
- periodKey = 46;
- slashKey = 47;
- questionmarkKey = 63;
-
- PopupDLOG = 3001;
- popup1Item = 3;
- popup2Item = 7;
- defaultItem = 5;
-
- normalPopupID = 11;
- smallPopupID = 12;
-
- PROCEDURE doPopupDialog;
-
- IMPLEMENTATION
-
- TYPE
- popupInfo = RECORD
- hMenu: MenuHandle;
- selectedItem: integer;
- smallFont : Boolean;
- END;
- DialogGlobals = RECORD
- menus : array [normalPopupID..smallPopupID] of popupInfo;
- END;
- DialogGlobalsPtr = ^DialogGlobals;
-
- FUNCTION ItemToMenuID(item:integer):integer;
- BEGIN
- IF item = popup1Item THEN ItemToMenuID:= normalPopupID ELSE ItemToMenuID := smallPopupID;
- END;
-
- PROCEDURE FakeClick (VAR theDialog: DialogPtr; theButton: Integer);
- { select/deselect a button in a Dialog }
- VAR
- theType: Integer;
- itemHandle: Handle;
- iRect: Rect;
- Ticks: LongInt;
- BEGIN
- GetDialogItem(theDialog, theButton, theType, itemHandle, iRect);
- HiliteControl(ControlHandle(itemHandle), On);
- Delay(8, Ticks);
- HiliteControl(ControlHandle(itemHandle), Off);
- END; { of proc FakeClick }
-
- PROCEDURE DrawDefaultBtn (theDialog: DialogPtr; ItemNumber: Integer);
- { heavy black outline }
- VAR
- iType: Integer;
- itemHdl: Handle;
- ps: PenState;
- iRect: Rect;
- BEGIN
- SetPort(theDialog); { set window to current graf port }
- GetDialogItem(theDialog, ItemNumber, iType, itemHdl, iRect); { get location }
- GetPenState(ps); { save current pen }
- PenNormal;
- PenSize(3, 3);
- InsetRect(iRect, -4, -4);
- FrameRoundRect(iRect, 16, 16);
- SetPenState(ps); { restore old pen }
- END; { of proc DrawDefaultBtn }
-
-
- PROCEDURE UpdatePopUp (theDialog: DialogPtr; Item: Integer);
- { draw popup menu }
- VAR
- aRect: Rect;
- theGlobals: DialogGlobalsPtr;
- IsNovice: boolean;
- theType: Integer;
- itemHdl: Handle;
- iRect: Rect;
- menuID:integer;
- BEGIN
- theGlobals := DialogGlobalsPtr(GetWRefCon(theDialog));
- menuID := ItemToMenuID(Item);
- GetDialogItem(theDialog, Item, theType, itemHdl, aRect);
- InsetRect(aRect, -2, -2);
- EraseRect(aRect);
- InsetRect(aRect, 2, 2);
-
- IF theGlobals^.menus[menuID].smallFont THEN BEGIN
- TextSize(9);
- TextFont(geneva);
- END;
- MDEF_CalcItemSize(theGlobals^.menus[menuID].hMenu, theGlobals^.menus[menuID].selectedItem, aRect);
-
- MoveTo(aRect.left + 2, aRect.bottom);
- LineTo(aRect.right, aRect.bottom);
- MoveTo(aRect.right, aRect.top + 2);
- LineTo(aRect.right, aRect.bottom);
-
- MoveTo(aRect.left + 6, aRect.bottom - 5); { move to text position }
- FillRect(aRect, qd.white);
-
- MDEF_DrawItem(theGlobals^.menus[menuID].hMenu, theGlobals^.menus[menuID].selectedItem, aRect);
-
- FrameRect(aRect);
- SetDialogItem(theDialog, Item, theType, itemHdl, aRect);
- IF theGlobals^.menus[menuID].smallFont THEN BEGIN
- TextSize(0);
- TextFont(0);
- END;
- END;
-
-
- FUNCTION PopUpSelectWithWindowFont (theMenu : MenuHandle; popPt: Point; popupItem: integer; useWFont: boolean): integer;
- VAR
- item: integer;
- itemMark : char;
- oldSysFont, oldWMgrFont, oldCWMgrFont: integer;
- oldSysSize, oldWMgrSize, oldCWMgrSize: integer;
- saveFontFam: integer;
- curPort: GrafPtr;
- wMgrPort: GrafPtr;
- wMgrCPort: CGrafPtr;
- theWorld:SysEnvRec;
- BEGIN
- oldSysFont := LMGetSysFontFam;
- oldSysSize := LMGetSysFontSize;
- GetPort(curPort);
- IF ((curPort^.txFont = oldSysFont) & (curPort^.txSize = oldSysSize)) THEN
- useWFont := false;
-
- IF useWFont THEN BEGIN
- { hack to fix bugs caused by programs that mess up the WindowMgr port(s)
- (e.g. MacWrite & Word) - thanks to Leonard Rosenthal for soln }
- GetWMgrPort(wMgrPort);
- SetPort(wMgrPort);
- oldWMgrFont := wMgrPort^.txFont;
- oldWMgrSize := wMgrPort^.txSize;
- TextFont(wMgrPort^.txFont);
- TextSize(wMgrPort^.txSize);
- IF ((SysEnvirons (1, theWorld) = noErr) & (theWorld.hasColorQD)) THEN BEGIN
- GetCWMgrPort(wMgrCPort);
- SetPort(GrafPtr(wMgrCPort));
- oldCWMgrFont := wMgrCPort^.txFont;
- oldCWMgrSize := wMgrCPort^.txSize;
- TextFont(wMgrCPort^.txFont);
- TextSize(wMgrCPort^.txSize);
- END
- ELSE
- theWorld.hasColorQD:=false;
- { end-of-hack }
-
- SetPort(curPort);
-
- LMSetSysFontFam(curPort^.txFont);
- LMSetSysFontSize(curPort^.txSize);
- LMSetLastSPExtra(longint(-1));
- END;
-
- IF (popupItem > 0) THEN BEGIN
- GetItemMark(theMenu, popupItem, itemMark);
- IF useWFont THEN
- SetItemMark(theMenu, popupItem, '*')
- ELSE
- SetItemMark(theMenu, popupItem, char(checkMark));
- END;
-
- CalcMenuSize(theMenu);
- item := PopUpMenuSelect(theMenu, popPt.v, popPt.h, popupItem);
-
- IF (popupItem > 0) THEN
- SetItemMark(theMenu, popupItem, itemMark);
-
- IF useWFont THEN BEGIN
- { part 2 of hack }
- SetPort(wMgrPort);
- TextFont(oldWMgrFont);
- TextSize(oldWMgrFont);
- IF theWorld.hasColorQD THEN BEGIN
- SetPort(GrafPtr(wMgrCPort));
- TextFont(oldCWMgrFont);
- TextSize(oldCWMgrSize);
- END;
- { end-of-hack-part-2 }
-
- SetPort(curPort);
-
- LMSetSysFontSize(oldSysSize);
- LMSetSysFontFam(oldSysFont);
- LMSetLastSPExtra(longint(-1));
- END;
-
- PopUpSelectWithWindowFont := item;
- END;
-
- PROCEDURE HandleMouseDown (theDialog:DialogPtr; itemHit: integer);
- VAR
- theGlobals: DialogGlobalsPtr;
- iType: integer;
- iRect: Rect;
- iHandle: Handle;
- popupRect: Rect;
- popupResult:integer;
- menuID:integer;
- BEGIN
- theGlobals := DialogGlobalsPtr(GetWRefCon(theDialog));
- menuID := ItemToMenuID(itemHit);
- CASE itemHit OF
- popup1Item, popup2Item: BEGIN
- GetDialogItem(theDialog, itemHit, iType, iHandle, iRect);
- SetRect(popupRect, iRect.left , iRect.top, iRect.left + theGlobals^.menus[menuID].hMenu^^.menuWidth + 4, iRect.bottom + 2);
- LocalToGlobal(popupRect.topLeft);
- LocalToGlobal(popupRect.botRight);
- InsetRect(iRect, 1, 1);
- {InvertRect(iRect);}
-
- IF theGlobals^.menus[menuID].smallFont THEN BEGIN
- TextFont(geneva);
- TextSize(9);
- END;
- popupResult := PopUpSelectWithWindowFont(theGlobals^.menus[menuID].hMenu, popupRect.topLeft, theGlobals^.menus[menuID].selectedItem, theGlobals^.menus[menuID].smallFont);
- IF theGlobals^.menus[menuID].smallFont THEN BEGIN
- TextSize(0);
- TextFont(0);
- END;
-
- {InvertRect(iRect);}
- IF (popupResult > 0) AND (LoWord(popupResult) <> theGlobals^.menus[menuID].selectedItem) THEN BEGIN
- CheckItem(theGlobals^.menus[menuID].hMenu, theGlobals^.menus[menuID].selectedItem, False);
- theGlobals^.menus[menuID].selectedItem := LoWord(popupResult);
- UpdatePopUp(theDialog, itemHit);
- END;
- END;
- OTHERWISE
- ;
- END;
- END;
-
- PROCEDURE HandleEvents (theDialog:DialogPtr);
- VAR
- theGlobals: DialogGlobalsPtr;
- eventOccured: boolean;
- theErr: longint;
- ShiftUsed, CmdKeyUsed, BadKey: boolean;
- itemHit: integer;
- theEvent: EventRecord;
- thePoint: Point;
- theKey: integer;
- whichWindow: WindowPtr; { Dummy,cause we have no windows}
- windowLoc: integer;
- matchedItem: longint;
- menuNum: Integer; { Res ID of the menu Selected }
- itemNum: Integer; { The item number selected }
- BEGIN
- theGlobals := DialogGlobalsPtr(GetWRefCon(theDialog));
- REPEAT
- eventOccured := GetNextEvent(everyEvent, theEvent);
- IF eventOccured THEN BEGIN
- IF IsDialogEvent(theEvent) THEN
- IF DialogSelect(theEvent, DialogPtr(whichWindow), itemHit) THEN
- HandleMouseDown(DialogPtr(whichWindow), itemHit);
- CASE theEvent.what OF
- keyDown, autoKey:{ any key down! }
- BEGIN
- theKey := BitAnd(theEvent.message, charCodeMask); { decode char }
- CmdKeyUsed := (BitAnd(theEvent.modifiers, cmdKey) <> 0); { cmd key down? }
- ShiftUsed := (BitAnd(theEvent.modifiers, shiftKey) <> 0); { shift key down? }
- CASE theKey OF
- enterKey, CR: { OK Button equivalents }
- BEGIN
- itemHit := ok;
- FakeClick(theDialog, itemHit);
- END;
- OTHERWISE
- IF CmdKeyUsed & (theKey = periodKey) THEN BEGIN
- FakeClick(theDialog, cancel);
- itemHit := cancel;
- END ELSE BEGIN
- matchedItem := MDEF_MenuKey(theEvent.message, theEvent.modifiers, theGlobals^.menus[normalPopupID].hMenu);
- IF (matchedItem > 0) THEN BEGIN
- menuNum := HiWrd(matchedItem); { get the menu number }
- itemNum := LoWrd(matchedItem); { get the item number }
- IF menuNum = normalPopupID THEN BEGIN
- theGlobals^.menus[menuNum].selectedItem := itemNum;
- UpdatePopUp(theDialog, 3);
- END ELSE IF menuNum = smallPopupID THEN BEGIN
- theGlobals^.menus[menuNum].selectedItem := itemNum;
- UpdatePopUp(theDialog, 7);
- END;
- END;
- END;
- END;
- END;
- mouseDown: { we had a mouse-down theEvent }
- BEGIN
- windowLoc := FindWindow(theEvent.where, whichWindow); { find out where }
- CASE windowLoc OF { now case on the location }
- inMenuBar: BEGIN
- SysBeep(1);
- END;
- inSysWindow:
- SystemClick(theEvent, whichWindow); {It was in a desk acc }
- inDrag: BEGIN
- DragWindow(whichWindow, theEvent.where, GetGrayRgn^^.rgnBBox);
- END;
- inContent:
- IF FrontWindow <> whichWindow THEN
- SelectWindow(whichWindow);
- OTHERWISE BEGIN
- END;
- END;
- END;
- OTHERWISE BEGIN
- IF DialogSelect(theEvent, DialogPtr(whichWindow), itemHit) THEN BEGIN END;
- END;
- END;
- END;
- UNTIL itemHit IN [ok, cancel];
- END;
-
-
- PROCEDURE doPopupDialog;
- VAR
- theDialog: DialogPtr;
- iType: integer;
- iRect: Rect;
- iHandle: Handle;
- popupRect: Rect;
- theGlobals: DialogGlobals;
- BEGIN
- theDialog := GetNewDialog(PopupDLOG, NIL, Pointer(-1));
- IF theDialog = NIL THEN BEGIN
- SysBeep(1);
- exit(doPopupDialog);
- END;
- SetPort(theDialog);
-
- SetWRefCon(theDialog, longint(@theGlobals));
-
- theGlobals.menus[normalPopupID].hMenu := GetMenu(normalPopupID);
- InsertMenu(theGlobals.menus[normalPopupID].hMenu, -1);
- CalcMenuSize(theGlobals.menus[normalPopupID].hMenu);
- theGlobals.menus[normalPopupID].selectedItem := 1;
- theGlobals.menus[normalPopupID].smallFont := FALSE;
- GetDialogItem(theDialog, popup1Item, iType, iHandle, iRect);
- SetDialogItem(theDialog, popup1Item, userItem, Handle(NewUserItemProc(@UpdatePopUp)), iRect);
-
- theGlobals.menus[smallPopupID].hMenu := GetMenu(smallPopupID);
- InsertMenu(theGlobals.menus[smallPopupID].hMenu, -1);
- CalcMenuSize(theGlobals.menus[smallPopupID].hMenu);
- theGlobals.menus[smallPopupID].selectedItem := 1;
- theGlobals.menus[smallPopupID].smallFont := TRUE;
- GetDialogItem(theDialog, popup2Item, iType, iHandle, iRect);
- SetDialogItem(theDialog, popup2Item, userItem, Handle(NewUserItemProc(@UpdatePopUp)), iRect);
-
- GetDialogItem(theDialog, defaultItem, iType, iHandle, iRect);
- SetDialogItem(theDialog, defaultItem, userItem, Handle(NewUserItemProc(@DrawDefaultBtn)), iRect);
-
- ShowWindow(theDialog);
- HandleEvents(theDialog);
-
- DeleteMenu(normalPopupID);
- DeleteMenu(smallPopupID);
- DisposeDialog(theDialog);
- END;
-
- END.
-